package com.binhthuan.catechist.server.service;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.binhthuan.catechist.server.ErrorObject;
import com.binhthuan.catechist.server.QueryObject;
import com.binhthuan.catechist.server.ResponseObject;
import com.binhthuan.catechist.server.bus.DateBUS;
import com.binhthuan.catechist.server.bus.YearBUS;
import com.binhthuan.catechist.server.domain.Date;
import com.binhthuan.catechist.server.domain.Year;
import com.binhthuan.catechist.shared.constant.Action;
import com.binhthuan.catechist.shared.constant.Parameter;

public class DateServlet extends AbstractServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 8427405626121531849L;

    @Override
    protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        addSchoolDate(request, response);
    }

    @Override
    protected void fetch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (request.getParameter(Parameter.ID) != null) {
            getSchoolDate(request, response);
        } else if (request.getParameter(Parameter.YEAR) != null) {
            getSchoolDateBySchoolYear(request, response);
        } else if (request.getParameter(Parameter.COURSE) != null) {
            getSchoolDateByCourse(request, response);
        }
    }

    @Override
    protected void remove(HttpServletRequest request, HttpServletResponse response, boolean confirmation) throws ServletException,
            IOException {
        deleteSchoolDate(request, response);
    }

    @Override
    protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        updateSchoolDate(request, response);
    }

    /**
     * @param request
     * @param response
     * @throws IOException
     */
    private void getSchoolDateByCourse(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            int classId = Integer.parseInt(request.getParameter(Parameter.COURSE));
            int startRow = request.getParameter(Action.Information.START_ROW) == null ? 0 : Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = request.getParameter(Action.Information.END_ROW) == null ? 0 : Integer.parseInt(request.getParameter(Action.Information.END_ROW));
        
            // Lấy năm học của lớp.
            YearBUS yearBus = new YearBUS();
            Year correspondingYear = yearBus.getSchoolYearByCourse(classId);

            DateBUS bus = new DateBUS();
            QueryObject shoolDays = bus.getSchoolDateBySchoolYear(correspondingYear.getId().intValue(), startRow, endRow - startRow);

            sendResponse(new ResponseObject(shoolDays).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    /**
     * @param request
     * @param response
     * @throws IOException
     */
    private void getSchoolDate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String id = request.getParameter(Parameter.ID);

        try {
            int dateId = Integer.parseInt(id);

            DateBUS dateBus = new DateBUS();
            Date date = dateBus.getSchoolDateById(dateId);

            sendResponse(new ResponseObject(date).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    /**
     * @param request
     * @param response
     * @throws IOException
     */
    private void getSchoolDateBySchoolYear(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            int yearId = Integer.parseInt(request.getParameter(Parameter.YEAR));
            int startRow = Integer.parseInt(request.getParameter(Action.Information.START_ROW));
            int endRow = Integer.parseInt(request.getParameter(Action.Information.END_ROW));

            DateBUS bus = new DateBUS();
            QueryObject shoolDays = bus.getSchoolDateBySchoolYear(yearId, startRow, endRow - startRow);

            sendResponse(new ResponseObject(shoolDays).toJson());
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void addSchoolDate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String liturgicalDate = request.getParameter(Parameter.LITURGICAL_DATE);
        String dayString = request.getParameter(Parameter.DATE_OF_YEAR);
        String yearString = request.getParameter(Parameter.YEAR);
        ErrorObject error = null;

        try {
            int yearId = Integer.parseInt(yearString);
            java.util.Date date = dateFormatter.parse(dayString);

            DateBUS dateBus = new DateBUS();
            // Bị trùng ngày học
            if (dateBus.getSchoolDateByDate(date) != null) {
                error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.DATE_OF_YEAR, getMessagesFactory().schoolDateIsDuplicated());
                sendResponse(error.toJson());
                return;
            }

            YearBUS yearBus = new YearBUS();
            Year currentYear = yearBus.getSchoolYearById(yearId);

            if (!checkSchoolDateInRange(date, currentYear)) {
                error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.DATE_OF_YEAR, getMessagesFactory().outOfSchoolYearRange());
                sendResponse(error.toJson());
                return;
            }

            Date newDate = new Date(date, liturgicalDate);
            newDate.setYear(currentYear);

            if (dateBus.save(newDate)) {
                sendResponse(new ResponseObject(newDate).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void updateSchoolDate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String dateId = request.getParameter(Parameter.ID);
        String liturgicalDate = request.getParameter(Parameter.LITURGICAL_DATE);
        String dayString = request.getParameter(Parameter.DATE_OF_YEAR);
        String yearIdString = request.getParameter(Parameter.YEAR);
        ErrorObject error = null;

        try {
            int id = Integer.parseInt(dateId);
            int yearId = Integer.parseInt(yearIdString);

            java.util.Date newDate = dateFormatter.parse(dayString);

            DateBUS dateBus = new DateBUS();
            Date checkDate = dateBus.getSchoolDateByDate(newDate);

            // Bị trùng ngày học
            if (checkDate != null && checkDate.getId() != id) {
                error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.DATE_OF_YEAR, getMessagesFactory().schoolDateIsDuplicated());
                sendResponse(error.toJson());
                return;
            }

            YearBUS yearBus = new YearBUS();
            Year currentYear = yearBus.getSchoolYearById(yearId);

            if (!checkSchoolDateInRange(newDate, currentYear)) {
                error = new ErrorObject(STATUS_VALIDATION_ERROR);
                error.addError(Parameter.DATE_OF_YEAR, getMessagesFactory().outOfSchoolYearRange());
                sendResponse(error.toJson());
                return;
            }

            Date currentDate = dateBus.getSchoolDateById(id);
            currentDate.setDateOfYear(newDate);
            currentDate.setLiturgicalDate(liturgicalDate);
            currentDate.setYear(currentYear);

            if (dateBus.save(currentDate)) {
                sendResponse(new ResponseObject(currentDate).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    private void deleteSchoolDate(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String dateId = request.getParameter(Parameter.ID);

        try {
            int id = Integer.parseInt(dateId);

            DateBUS dateBus = new DateBUS();
            if (dateBus.deleteDate(id)) {
                sendResponse(new ResponseObject((Object) null).toJson());
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }

    public boolean checkSchoolDateInRange(java.util.Date day, Year schoolYear) {
        return day.compareTo(schoolYear.getEndDate()) <= 0 && day.compareTo(schoolYear.getStartDate()) >= 0;
    }
}
